package com.talkyun.openx.interceptor;

import com.talkyun.openx.server.core.AbstractInterceptor;
import com.talkyun.openx.server.core.InterceptorException;
import com.talkyun.openx.server.core.ServiceContext;
import com.talkyun.openx.server.core.ServiceRequest;
import com.talkyun.utils.subnet.AddressUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

import static com.talkyun.openx.server.core.ServiceContext.REQ_IP;

public class LimitAddressInterceptor extends AbstractInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(LimitAddressInterceptor.class);

    private List<String> blackList;
    private String blackListUrl;
    private List<String> whiteList;
    private String whiteListUrl;

    public void setBlackListUrl(String url) {
        this.blackListUrl = url;
    }

    public void setWhiteListUrl(String url) {
        this.whiteListUrl = url;
    }

    public void setBlackList(List<String> blackList) {
        this.blackList = blackList;
    }

    public void setWhiteList(List<String> whiteList) {
        this.whiteList = whiteList;
    }

    @Override
    public void doMessageIn(ServiceRequest sr) {
        try {
            this.doLimit();
        } catch (Throwable t) {
            logger.error("Error with limit address!", t);
        }
    }

    private void doLimit() {
        // 0. if white ip, ok
        // 1. else if black ip, reject
        // 2. last no white|black ip, ok
        ServiceContext ctx = ServiceContext.get();
        String ip = ctx.getString(REQ_IP, null);
        if (!isWhiteIp(ip) && isBlackIp(ip)) {
            throw new InterceptorException("Black list ip " + ip, null);
        }
    }

    private boolean isWhiteIp(String ip) {
        if (whiteList == null || whiteList.isEmpty() || ip == null) {
            return false;
        }
        for (String src : whiteList) {
            if (AddressUtils.isInRange(ip, src)) {
                return true;
            }
        }
        return false;
    }

    private boolean isBlackIp(String ip) {
        if (blackList == null || blackList.isEmpty() || ip == null) {
            return false;
        }
        for (String src : blackList) {
            if (AddressUtils.isInRange(ip, src)) {
                return true;
            }
        }
        return false;
    }
}